﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System.ComponentModel;
using System.Xml;
using NetJsWire.JsonRpcHandler;
using NetJsWire.JsonRpcHandler.Attributes;
using NetJsWire.Widgets.Renderers.Core;
using Newtonsoft.Json;

namespace NetJsWire.Widgets.Renderers.Data
{
    [ClassName( "Ext.data.Store" )]
    internal class Store : BasicComponent
    {
        private readonly Widgets.Data.Store _baseStore;
        protected bool ShouldRenderData = true;
        private XmlNode _columnsNode;
        private XmlNode _dataNode;

        public Store( object baseObject )
            : base( baseObject )
        {
            _baseStore = ( Widgets.Data.Store ) baseObject;
        }

        public override void Render()
        {
            if ( !Rendered )
            {
                ClientID = InternalID;
                EnsureParentNodePosition();
                //if ( _baseStore.ConfigOptions.Listeners != null && _baseStore.ConfigOptions.Listeners.Count > 0 )
                //{
                //    SetConstructionProperty( "listeners", JsonConvert.SerializeObject( _baseStore.ConfigOptions.Listeners, Formatting.None, new JsonConverter[] { new ListenerCollectionJsonConverter(), new ListenerJsonConverter() } ) );
                //}
                RenderColumns();
            }
            else
            {
                if ( ControlNode.Attributes[ "render" ] == null ||
                     ControlNode.Attributes[ "render" ].InnerText.ToLower() != "true" )
                    SetAttribute( ControlNode, "render", false );
            }

            base.Render();

            if ( ShouldRenderData )
                RenderData();
        }

        protected virtual void RenderColumns()
        {
            if ( ControlNode[ "columns" ] == null )
                _columnsNode = ControlNode.AppendChild( WebApplication.Instance.XmlDocument.CreateNode( XmlNodeType.Element, "columns", "" ) );
            else
                _columnsNode.RemoveAll();

            foreach ( var col in _baseStore.Columns )
            {
                var colNode = _columnsNode.AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "column", "" ) );
                colNode.InnerText = col;
            }
        }

        private void RenderData()
        {
            if ( ControlNode[ "data" ] == null )
                _dataNode = ControlNode.AppendChild( WebApplication.Instance.XmlDocument.CreateNode( XmlNodeType.Element, "data", "" ) );
            else
                _dataNode.RemoveAll();

            var ibl = _baseStore.DataSource as IBindingList;
            if ( ibl != null )
            {
                XmlNode rowNode;
                foreach ( var o in ibl )
                {
                    rowNode =
                        _dataNode.AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "datanode", "" ) );
                    var rowText = "[";
                    foreach ( var col in _baseStore.Columns )
                    {
                        rowText += JsonConvert.SerializeObject( FilterItemOnProperty( o, col ) );
                            //Jayrock.Json.Conversion.JsonConvert.ExportToString( FilterItemOnProperty( o, col ) ).Replace
                            //    ( "[", "" ).Replace( "]", "" );
                        rowText += ",";
                    }

                    if ( rowText.EndsWith( "," ) )
                        rowText.Remove( rowText.Length - 1, 1 );

                    rowNode.InnerText = rowText + "]";
                }
            }
        }

        private static object FilterItemOnProperty( object item, string field )
        {
            if ( ( item != null ) && ( field.Length > 0 ) )
            {
                var descriptor = TypeDescriptor.GetProperties( item ).Find( field, true );
                if ( descriptor != null )
                {
                    item = descriptor.GetValue( item );
                }
            }
            return item;
        }
    }
}